// TODO: CODE REVIEW & CLEANUP!
//
// MusicLoadPlaylistScreen.xaml.cs
//

using System;
using System.Windows;
using System.Windows.Controls;
using System.Xml;
using HomeUX.ClientControlSupport;
using HomeUX.Controls;
using HomeUX.Synchronization;
using HomeUX.Utilities;

namespace HomeUX.MusicClientLibrary
{

public partial class MusicLoadPlaylistScreen : UserControl
{
    MusicClientHelper _musicClientHelper;

    Style _playlistTextStyle;

    /// <summary>
    /// A <n>String.Format</n>-style format string to use for <n>HeaderTextBlock</n>.  Initialized
    /// from the design-time text value of  <n>HeaderTextBlock</n>.
    /// </summary>
    string _headerFormatString;

    public MusicLoadPlaylistScreen()
    {
        InitializeComponent();

        // initialize <_headerFormatString>
        _headerFormatString = HeaderTextBlock.Text;

        Loaded += MusicLoadPlaylistScreen_Loaded;
    }

    void MusicLoadPlaylistScreen_Loaded(object sender, RoutedEventArgs e)
    {
        _playlistTextStyle = (Style)Resources["PlaylistTextStyle"];

        _musicClientHelper = new MusicClientHelper(this, BeginLoadingDataFromMusicServer,
            OnParcelReceived);
        
        HeaderTextBlock.Text = String.Format(_headerFormatString, _musicClientHelper.MusicDeviceName);

        _musicClientHelper.LoadingMessage = "Loading playlist names...";
        _musicClientHelper.Screen.Opened += OnScreenOpened;
    }

    void OnScreenOpened(object sender, EventArgs e)
    {
        // do the same thing we'd do if we were waiting for the music server to become available
        _musicClientHelper.TryToLoadData();
    }

    void BeginLoadingDataFromMusicServer()
    {
		PlaylistsListBox.Items.Clear();
        NoPlaylistsMessage.Visibility = Visibility.Collapsed;
        string command = ParsedSyncNodeCommand.Format("GetPlaylists",
            "RecipientId", XmlConvert.ToString(_musicClientHelper.RecipientId));
        _musicClientHelper.MusicDeviceNode.ExecuteCommand(command);
    }

    void OnParcelReceived(Guid recipientId, XmlReader reader)
    {
        // do nothing if we're in an error state
        if (_musicClientHelper.LoadState == MusicClientLoadState.Error)
            return;

        try
        {
            foreach (XmlElementInfo element in XmlElementInfo.EnumerateElements(reader))
            {
                switch (element.Name)
                {

                case "Playlist":

                    AddPlaylistToList(element.GetRequiredAttribute("Name"));
                    break;

                case "/Playlists":

                    NoPlaylistsMessage.Visibility =
                        ClientUtil.GetVisibility(PlaylistsListBox.Items.Count == 0);
                    _musicClientHelper.OnDataLoaded();
                    PlaylistsListBox.Focus();
                    break;
                }
            }
        }
        catch (InvalidOperationException ex)
        {
            ClientGlobals.Alert(AlertType.Warning,
                "Invalid reply from server: {0}", ex.Message);
        }
    }

    /// <summary>
    /// Called when the request begun by <r>RequestPlaylists</r> has completed.  This method is
    /// called once for each playlist.
    /// </summary>
    void AddPlaylistToList(string name)
    {
        var textBlock = new TextBlock()
        {
            Text = name,
            Tag = name,
            Style = _playlistTextStyle
        };
        PlaylistsListBox.Items.Add(textBlock);
    }

    private void PlaylistsListBox_ItemClick(object sender, ItemClickEventArgs e)
    {
        TouchListBoxItem button;
        if (PlaylistsListBox.TryMapItemToButton(e.Item, out button))
            PlaylistsListBox.TrySetPseudofocus(button);

        var playlistName = (string)((TextBlock)e.Item).Tag;
        
        string command = ParsedSyncNodeCommand.Format("LoadPlaylist",
            "PlaylistName", playlistName);

        TouchMessageBox messageBox = TouchMessageBox.Show(this, "Loading playlist...", null, null);
        _musicClientHelper.WaitForMusicDeviceNode(delegate
        {
            messageBox.Close(false);
            _musicClientHelper.GoToMusicScreen("Queue");
        });

        _musicClientHelper.MusicDeviceNode.ExecuteCommand(command);
    }
}

}

